import Koa from 'koa'
const app = new Koa();
import views from 'koa-views';
import json from 'koa-json';
import bodyparser from 'koa-bodyparser';
import jwt from './middlewares/permission'
import parameter from './middlewares/parameter'
import redisLoader, { redisUri } from './loaders/loader-redies';
import cors from 'koa2-cors'; // 跨域
import { Router } from '@libs/koa-action-decorator' // 使用装饰器router
import http from 'http';
import schedule from './schedule'
import startArgv from './libs/dt-start-argv';
import loggerLoader from './loaders/loader-logger'
const path = require('path');
import moment from 'moment';
// 获取密匙
import { SECRET, EXPIRES, REDIS_CONF } from './config/index';
import { ErrorModel } from '@utils/respond/ResModel';


// 跨域问题处理
app.use(cors());

// 参数处理
app.use(parameter())
    // 异常处理
app.use(async(ctx, next) => {
    try {
        await next()
    } catch (err) {
        console.log('err', err);

        ctx.status = err.statusCode || err.status || 500
        ctx.body = {
            errorcode: 1000,
            message: '请求异常'
        }
    }
})

// 持久化日志
loggerLoader.onLoad(path.resolve(__dirname, '../asset/logs'))

app.use(jwt.permission({
    secret: SECRET,
    expires: EXPIRES
}))



// 路由自动加载
let router = Router({
    controllerDir: path.resolve(__dirname, 'modules'),
    options: { debug: true }
})

app.use(jwt.unless({
        secret: SECRET,
        path: router.jwtUnlessPaths
    }))
    // middlewares
app.use(
    bodyparser({
        enableTypes: ['json', 'form', 'text'],
    })
);
app.use(json());

app.use(require('koa-static')(__dirname + '/public'));

app.use(
    views(__dirname + '/views', {
        extension: 'ejs',
    })
);

// 日志打印
app.use(async(ctx, next) => {
  try {
    const start = new Date();
    await next();
    const ms = new Date() - start;
    global.logger.api(`${moment().format('YYYY-MM-DD HH:mm:ss').green}：${ctx.method} ${ctx.url} - ${ms}ms
      -------- query:${JSON.stringify(ctx.request.query)}
      -------- body: ${JSON.stringify(ctx.request.body)}
      -------- res: ${ctx.response.status === 200?'200':JSON.stringify(ctx.body)}`);
  }catch (e) {
    global.logger.error(`${moment().format('YYYY-MM-DD HH:mm:ss').red}：${ctx.method} ${ctx.url}
      -------- query:${JSON.stringify(ctx.request.query)}
      -------- body: ${JSON.stringify(ctx.request.body)}
      -------- error: ${e.toString()}`);
    ctx.response.status = 500;
    ctx.body = new ErrorModel({message:e.toString()})
  }
});


// 中间件对401错误进行检查,koa-jwt插件就可以对token进行验证，验证就是检查秘钥是否相等，相等就可以接着进行请求。
app.use(async(ctx, next) => {
    return next().catch((err) => {
        if (err.status === 401) {
            ctx.status = 401;
            ctx.body = {
                code: 401,
                msg: err.message,
            };
        } else {
            throw err;
        }
    });
});


global.apis = router.paths //保存系统所有api到全局变量中

app.use(router.routes())

redisLoader.onLoad(REDIS_CONF)

schedule();

// error-handling
app.on('error', (err, ctx) => {
    console.error('server error', err, ctx);
});


let args = startArgv.getArgs({ port: 3000 })
let server = http.Server(app.callback())
server.listen(args.port, () => {
    console.log(`项目启动成功，正在监听${args.port}端口.`.green)
})


module.exports = app;
